package com.faithbj.service.impl;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

import javax.annotation.Resource;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.faithbj.common.model.CheckTotal;
import com.faithbj.common.model.EntrustInfo;
import com.faithbj.common.model.fm.Employment;
import com.faithbj.common.model.fm.FamilyMember;
import com.faithbj.common.model.fm.FamilyMemberIncome;
import com.faithbj.common.model.fm.property.FamilyMemberProperty;
import com.faithbj.common.utils.JsonUtil;
import com.faithbj.constant.Constant;
import com.faithbj.dao.CheckTotalDao;
import com.faithbj.dao.EmploymentDao;
import com.faithbj.dao.EntrustInfoDao;
import com.faithbj.dao.FamilyMemberDao;
import com.faithbj.dao.FamilyMemberIncomeDao;
import com.faithbj.dao.FamilyMemberPropertyDao;
import com.faithbj.service.DataTransferService;

@Service("dataImpExpService")
@Transactional
public class DataTransferServiceImpl implements DataTransferService {
    private final Logger logger = LoggerFactory.getLogger(DataTransferServiceImpl.class);

    @Resource
    public CheckTotalDao checkTotalDao;
    @Resource
    public FamilyMemberIncomeDao familyMemberIncomeDao;
    @Resource
    public FamilyMemberDao familyMemberDao;
    @Resource
    public FamilyMemberPropertyDao familyMemberPropertyDao;
    @Resource
    public EntrustInfoDao entrustInfoDao;
    @Resource
    public EmploymentDao employmentDao;

    @Override
    public boolean exportDBFiles(List<String> checkTotalIds) {
        // 查询得到需要写入文件的数据列表
        List<CheckTotal> ctList = checkTotalDao.queryListByIds(checkTotalIds);

        List<FamilyMember> familyMemberList = new ArrayList<FamilyMember>();
        List<EntrustInfo> entrustInfoList = new ArrayList<EntrustInfo>();
        for (CheckTotal ct : ctList) {
            if (ct.getFamilyMembers() != null) {
                familyMemberList.addAll(ct.getFamilyMembers());
            }
            if (ct.getEntrustInfo() != null) {
                entrustInfoList.add(ct.getEntrustInfo());
            }
        }

        List<FamilyMemberIncome> fmIncomeList = new ArrayList<FamilyMemberIncome>();
        for (FamilyMember fm : familyMemberList) {
            if (fm.getIncome() != null) {
                fmIncomeList.add(fm.getIncome());
            }
        }

        List<String> fmIds = new ArrayList<String>();
        for (CheckTotal ct : ctList) {
            for (FamilyMember fm : ct.getFamilyMembers()) {
                fmIds.add(fm.getId());
            }
        }
        List<Employment> employmentList = employmentDao.queryByFmIds(fmIds);
        List<FamilyMemberProperty> propertyList = familyMemberPropertyDao.queryByFmIds(fmIds);

        // 多线程导出数据文件
        CountDownLatch doneSignal = new CountDownLatch(Constant.JSON_FILES.length);
        new Thread(new ExportWorker<CheckTotal>(Constant.JSON_FILE_CHECK_TOTAL, ctList, doneSignal)).start();
        new Thread(new ExportWorker<Employment>(Constant.JSON_FILE_EMPLOYMENT, employmentList, doneSignal)).start();
        new Thread(new ExportWorker<FamilyMemberProperty>(Constant.JSON_FILE_FAMILY_MEMBER_PROPERTY, propertyList,
                doneSignal)).start();

        try {
            doneSignal.await();
            // StringBuilder sb = new StringBuilder("");
            // for (String fmId : fmIds) {
            // sb.append(fmId).append(",");
            // }
            // int exeResult = ExecUtil.executeWithoutTimeout(Constant.EXP_WORKING_DIR_PATH, Constant.EXP_SHELL_COMMAND,
            // new String[] { sb.substring(0, sb.length() - 1) });
            // if (exeResult != 1) {
            // throw new RuntimeException("数据导出shell脚本执行失败!");
            // }
        } catch (InterruptedException e) {
            logger.error("多线程导出数据表到文件失败!", e);
        }
        return true;
    }

    @Override
    public boolean importDBFiles() {
        // int exeResult = ExecUtil.executeWithoutTimeout(Constant.EXP_WORKING_DIR_PATH, Constant.IMP_SHELL_COMMAND);
        // if (exeResult != 1) {
        // throw new RuntimeException("数据导入shell脚本执行失败!");
        // }

        // 导入数据库文件
        importJsonToDB();
        return true;
    }

    private void importJsonToDB() throws RuntimeException {
        File file = new File(Constant.IMP_FILE_PATH_PREFIX + Constant.JSON_FILE_CHECK_TOTAL);
        if (!file.exists()) {
            throw new RuntimeException("文件：" + file.getName() + "不存在");
        }

        String json = null;
        try {
            json = FileUtils.readFileToString(file);
        } catch (Exception e) {
            throw new RuntimeException("文件：" + file.getName() + "读取失败!", e);
        }

        CheckTotal[] checkTotals = JsonUtil.fromJson(json, CheckTotal[].class);
        List<EntrustInfo> entrustInfoList = new ArrayList<EntrustInfo>();
        List<CheckTotal> checkTotalList = new ArrayList<CheckTotal>();
        List<FamilyMemberIncome> familymemberIncomeList = new ArrayList<FamilyMemberIncome>();
        List<FamilyMember> familymemberList = new ArrayList<FamilyMember>();

        for (CheckTotal ct : checkTotals) {
           ct.setId(ct.getId().substring(0, ct.getId().length() - 2) + "N");
            //ct.setId(null);
            checkTotalList.add(ct);
            if (ct.getFamilyMembers() != null) {
                for (FamilyMember fm : ct.getFamilyMembers()) {
                   fm.setId(fm.getId().substring(0, fm.getId().length() - 2) + "N");
                    //fm.setId(null);
                    familymemberList.add(fm);
                    if (fm.getIncome() != null) {
                        FamilyMemberIncome income = fm.getIncome();
                        income.setId(income.getId().substring(0, income.getId().length() - 2) + "N");
                        //income.setId(null);
                        familymemberIncomeList.add(income);
                    }
                }
            }
            if (ct.getEntrustInfo() != null) {
                EntrustInfo entrustInfo = ct.getEntrustInfo();
                entrustInfo.setId(entrustInfo.getId().substring(0, entrustInfo.getId().length() - 2) + "N");
                //entrustInfo.setId(null);
                entrustInfoList.add(entrustInfo);
            }
        }

        for (EntrustInfo entrustInfo : entrustInfoList) {
            entrustInfoDao.save(entrustInfo);
        }
        for (CheckTotal ct : checkTotalList) {
            checkTotalDao.save(ct);
        }
        for (FamilyMemberIncome income : familymemberIncomeList) {
            familyMemberIncomeDao.save(income);
        }
        for (FamilyMember fm : familymemberList) {
            familyMemberDao.save(fm);
        }

    }

    private class ExportWorker<T> implements Runnable {
        private String fileName;
        private List<T> objectList;
        private CountDownLatch doneSignal;

        public ExportWorker(String fileName, List<T> objectList, CountDownLatch doneSignal) {
            this.fileName = fileName;
            this.objectList = objectList;
            this.doneSignal = doneSignal;
        }

        @Override
        public void run() {
            String json = JsonUtil.toJson(objectList);
            System.out.println(json);
            File file = new File(Constant.EXP_FILE_PATH_PREFIX + fileName);
            try {
                FileUtils.writeStringToFile(file, json, "utf-8");
                doneSignal.countDown();
            } catch (IOException e) {
                logger.error("数据表[" + fileName + "]导出到文件失败!", e);
            }
        }
    }

}
